package fr.sedoo.sos.xml;

import java.util.Iterator;

import net.opengis.gml.CodeType;
import net.opengis.gml.PointType;
import net.opengis.gml.StringOrRefType;
import net.opengis.sensorML.x101.CapabilitiesDocument.Capabilities;
import net.opengis.sensorML.x101.IdentificationDocument.Identification;
import net.opengis.sensorML.x101.IdentificationDocument.Identification.IdentifierList;
import net.opengis.sensorML.x101.IdentificationDocument.Identification.IdentifierList.Identifier;
import net.opengis.sensorML.x101.IoComponentPropertyType;
import net.opengis.sensorML.x101.OutputsDocument.Outputs.OutputList;
import net.opengis.sensorML.x101.SensorMLDocument;
import net.opengis.sensorML.x101.SensorMLDocument.SensorML;
import net.opengis.sensorML.x101.SensorMLDocument.SensorML.Member;
import net.opengis.sensorML.x101.SystemDocument;
import net.opengis.sensorML.x101.SystemType;
import net.opengis.sensorML.x101.TermDocument.Term;
import net.opengis.sos.x20.SosInsertionMetadataDocument;
import net.opengis.sos.x20.SosInsertionMetadataType;
import net.opengis.swe.x101.AnyScalarPropertyType;
import net.opengis.swe.x101.QuantityDocument.Quantity;
import net.opengis.swe.x101.SimpleDataRecordDocument;
import net.opengis.swe.x101.SimpleDataRecordType;
import net.opengis.swe.x101.TextDocument;
import net.opengis.swe.x101.TextDocument.Text;
import net.opengis.swes.x20.InsertSensorDocument;
import net.opengis.swes.x20.InsertSensorType;
import net.opengis.swes.x20.InsertSensorType.Metadata;
import net.opengis.swes.x20.InsertSensorType.ProcedureDescription;
import fr.sedoo.sos.domain.Phenomenon;
import fr.sedoo.sos.domain.Sensor;
import fr.sedoo.sssdata.server.sos.SensorMLConstants;
import fr.sedoo.sssdata.server.sos.XmlBeansUtils;

public class SensorUtils {

	public static String getInsertSensorRequest(Sensor sensor)
	{
		InsertSensorDocument doc = InsertSensorDocument.Factory.newInstance();
		InsertSensorType insertSensor = doc.addNewInsertSensor();
		insertSensor.setService(SensorMLConstants.SOS);
		insertSensor.setVersion(SensorMLConstants.VERSION);
		insertSensor.setProcedureDescriptionFormat("http://www.opengis.net/sensorML/1.0.1");
		ProcedureDescription procedureDescription = insertSensor.addNewProcedureDescription();

		SensorMLDocument docSML = SensorMLDocument.Factory.newInstance();
		SensorML sensorML = docSML.addNewSensorML();
		sensorML.setVersion("1.0.1");
		Member member = sensorML.addNewMember();

		SystemDocument aux = SystemDocument.Factory.newInstance();
		SystemType system = aux.addNewSystem();

		StringOrRefType description = system.addNewDescription();
		description.setStringValue("Informations for sensor "+sensor.getShortName().toLowerCase()+" in station "+sensor.getStation().getShortName());

		Identification identification = system.addNewIdentification();
		IdentifierList identifierList = identification.addNewIdentifierList();

		Identifier uniqueId = identifierList.addNewIdentifier();
		uniqueId.setName("URN");
		Term term = uniqueId.addNewTerm();
		term.setDefinition("urn:ogc:def:identifier:OGC:1.0:uniqueID");
		term.setValue(sensor.getUrn());

		Identifier shortName = identifierList.addNewIdentifier();
		shortName.setName("shortName");
		term = shortName.addNewTerm();
		term.setDefinition("urn:ogc:def:identifier:OGC:1.0:shortName");
		term.setValue(sensor.getShortName());

		Identifier longName = identifierList.addNewIdentifier();
		longName.setName("longName");
		term = longName.addNewTerm();
		term.setDefinition("urn:ogc:def:identifier:OGC:1.0:longName");
		term.setValue(sensor.getLongName());

		Identification offeringIdentification = system.addNewIdentification();
		offeringIdentification.setTitle("offerings");
		IdentifierList offeringIdentifierList = offeringIdentification.addNewIdentifierList();
		Identifier offeringIdentifier = offeringIdentifierList.addNewIdentifier();
		Term offeringTerm = offeringIdentifier.addNewTerm();
		offeringTerm.setValue(sensor.getOffering());
		offeringTerm.setDefinition("urn:ogc:def:identifier:OGC:offeringID");
		offeringIdentifier.setName("Offering for "+sensor.getUrn());

		CodeType name = system.addNewName();
		name.setStringValue(sensor.getLongName());

		PointType point = system.addNewSmlLocation().addNewPoint();
		point.setSrsName(sensor.getSrsName());
		point.addNewCoordinates().setStringValue(sensor.getLat()+" "+sensor.getLon());

		Capabilities capabilities = system.addNewCapabilities();

		SimpleDataRecordDocument dataRecordDocument = SimpleDataRecordDocument.Factory.newInstance();
		SimpleDataRecordType dataRecord = dataRecordDocument.addNewSimpleDataRecord();

		AnyScalarPropertyType featureOfInterestField = dataRecord.addNewField();
		TextDocument textDocument = TextDocument.Factory.newInstance();
		Text text = textDocument.addNewText();
		text.setDefinition("FeatureOfInterest identifier");
		text.setValue(sensor.getFeatureOfInterest());
		featureOfInterestField.set(textDocument);
		featureOfInterestField.setName("FeatureOfInterestID");
		capabilities.set(dataRecordDocument);
		capabilities.setName("featureOfInterest");
		
		OutputList outputList = system.addNewOutputs().addNewOutputList();
		Iterator<Phenomenon> phenomenonIterator = sensor.getPhenomena().iterator();
		while (phenomenonIterator.hasNext()) 
		{
			Phenomenon phenomenon = phenomenonIterator.next();
			IoComponentPropertyType output = outputList.addNewOutput();
			output.setName(phenomenon.getName());
			Quantity quantity = output.addNewQuantity();
			quantity.setDefinition(phenomenon.getUrn());
			quantity.addNewUom().setCode(phenomenon.getUnit());
		}
		
		Metadata metadata = insertSensor.addNewMetadata();
		SosInsertionMetadataDocument insertionMetadataDoc = SosInsertionMetadataDocument.Factory.newInstance();
		SosInsertionMetadataType insertionMetadata = insertionMetadataDoc.addNewSosInsertionMetadata();
		insertionMetadata.setObservationTypeArray(new String[] {"http://www.opengis.net/def/observationType/OGC-OM/2.0/OM_Measurement"});
		insertionMetadata.setFeatureOfInterestTypeArray(new String[] {"http://www.opengis.net/def/samplingFeatureType/OGC-OM/2.0/SF_SamplingPoint"});

		metadata.set(insertionMetadataDoc);

		phenomenonIterator = sensor.getPhenomena().iterator();
		while (phenomenonIterator.hasNext()) 
		{
			insertSensor.addObservableProperty(phenomenonIterator.next().getUrn());
		}
		
		member.set(aux);
		procedureDescription.set(docSML);
		
		return XmlBeansUtils.toString(doc);

	}

}
